<html><head><META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>3.3.&nbsp;Offline mode: separating instrumentation and execution</title><link href="../skin/css/doc.css" rel="stylesheet" type="text/css"><meta content="DocBook XSL Stylesheets V1.66.1" name="generator"><link rel="start" href="userguide.html" title="EMMA User Guide"><link rel="up" href="ar01s03.html" title="3.&nbsp;Getting Started (ANT)"><link rel="prev" href="ar01s03s02.html" title="3.2.&nbsp;<emmajava>: instrumenting Java classes
on-the-fly"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table summary="Navigation header" width="100%"><tr><th align="center" colspan="3">3.3.&nbsp;Offline mode: separating instrumentation and execution</th></tr><tr><td align="left" width="20%"><a accesskey="p" href="ar01s03s02.html"><img src="../images/prev.gif" alt="Prev"></a>&nbsp;</td><th align="center" width="60%">3.&nbsp;Getting Started (<span class="emphasis"><em>ANT</em></span>)</th><td align="right" width="20%">&nbsp;</td></tr></table><hr></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="N10291"></a>3.3.&nbsp;Offline mode: separating instrumentation and execution</h3></div></div></div><p>As convenient as the on-the-fly mode is, in many cases it is not
sufficient. For example, running a commercial J2EE container in a custom
instrumenting classloader is practically impossible. Certain (bad) coding
practices also fail for code executing in a custom classloader. Finally, in
large scale development there is a common need to collect and merge coverage
data from multiple execution runs and multiple JVM processes.</p><p>This is where separate instrument/execute/report phases are a
necessity. This section repeats the previous exercise using
<span><b class="command">&lt;emma&gt;</b></span> ANT task, which provides several subtasks
for managing offline instrumentation: <span><b class="command">&lt;instr&gt;</b></span>,
<span><b class="command">&lt;merge&gt;</b></span>, and <span><b class="command">&lt;report&gt;</b></span>. In
a typical ANT build each <span><b class="command">&lt;emma&gt;</b></span> tag acts as a
container for an arbitrary sequence of sub-tags. This design allows for a
simple form of build flow control, whereby entire sequences of EMMA commands
can be disabled at a single point.</p><p>Let's go back to the starting point of the previous section and
assume that you have a <tt class="filename">build.xml</tt> file with EMMA tasks
imported and the following build infrastructure created:</p><pre class="programlisting">
  &lt;!-- root directory for the example source code: --&gt; 
  &lt;property name="src.dir" value="${basedir}/src" /&gt;

  &lt;!-- javac class output directory: --&gt;
  &lt;property name="out.dir" value="${basedir}/out" /&gt;

  &lt;target name="init" &gt;
    &lt;mkdir dir="${out.dir}" /&gt;
    &lt;path id="run.classpath" &gt;
      &lt;pathelement location="${out.dir}" /&gt;
    &lt;/path&gt;
  &lt;/target&gt;

  &lt;target name="compile" depends="init" description="compiles the example source code" &gt;
    &lt;javac debug="on" srcdir="${src.dir}" destdir="${out.dir}" /&gt;
  &lt;/target&gt;

  &lt;target name="run" depends="init, compile" description="runs the examples" &gt;
    &lt;java classname="Main" classpathref="run.classpath" &gt;
 &lt;/target&gt;</pre><p>In a real world project the actual application could be either
an end user application or your test framework driver. Adding offline
coverage instrumentation and reporting to this build is not much harder than
it was in the command line tools case, in <a href="ar01s02s03.html" title="2.3.&nbsp;Offline mode: separating instrumentation and execution">Section&nbsp;2.3, &ldquo;Offline mode: separating instrumentation and execution&rdquo;</a>.
All you need to do is sandwich <span><b class="command">&lt;java&gt;</b></span> (or your test
framework driver, or anything that can run on Java classes) between EMMA's
<span><b class="command">&lt;instr&gt;</b></span> and
<span><b class="command">&lt;report&gt;</b></span>:</p><pre class="programlisting">
  &lt;target name="emma" description="turns on EMMA instrumentation/reporting" &gt;
    &lt;property name="emma.enabled" value="true" /&gt;
    <a name="B0-co" href="ar01s03s03.html#B0"><img border="0" alt="1" src="../images/callouts/1.png"></a>&lt;!-- EMMA instr class output directory: --&gt;
    &lt;property name="out.instr.dir" value="${basedir}/outinstr" /&gt;
    &lt;mkdir dir="${out.instr.dir}" /&gt;
  &lt;/target&gt;

  &lt;target name="run" depends="init, compile" description="runs the examples" &gt;
    &lt;emma enabled="${emma.enabled}" &gt;
      &lt;instr instrpathref="run.classpath"<a name="B0.5-co" href="ar01s03s03.html#B0.5"><img border="0" alt="2" src="../images/callouts/2.png"></a>
             destdir="${out.instr.dir}"	
             metadatafile="${coverage.dir}/metadata.emma"
             merge="true"
      /&gt;
    &lt;/emma&gt;

    <a name="B1-co" href="ar01s03s03.html#B1"><img border="0" alt="3" src="../images/callouts/3.png"></a>
    &lt;java classname="Main" fork="true"<a name="B2-co" href="ar01s03s03.html#B2"><img border="0" alt="4" src="../images/callouts/4.png"></a> &gt;
      &lt;classpath&gt;
       <a name="B3-co" href="ar01s03s03.html#B3"><img border="0" alt="5" src="../images/callouts/5.png"></a>&lt;pathelement location="${out.instr.dir}" /&gt;
        &lt;path refid="run.classpath" /&gt;
        &lt;path refid="emma.lib" /&gt;
      &lt;/classpath&gt; 
      &lt;jvmarg value="-Demma.coverage.out.file=${coverage.dir}/coverage.emma" /&gt;<a name="B4-co" href="ar01s03s03.html#B4"><img border="0" alt="6" src="../images/callouts/6.png"></a>
      &lt;jvmarg value="-Demma.coverage.out.merge=false" /&gt;
    &lt;/java&gt;

    &lt;emma enabled="${emma.enabled}" &gt;
      <a name="B5-co" href="ar01s03s03.html#B5"><img border="0" alt="7" src="../images/callouts/7.png"></a>&lt;report sourcepath="${src.dir}" &gt;
        &lt;fileset dir="${coverage.dir}" &gt;
          &lt;include name="*.emma" /&gt;<a name="B6-co" href="ar01s03s03.html#B6"><img border="0" alt="8" src="../images/callouts/8.png"></a>
        &lt;/fileset&gt;

        &lt;txt outfile="${coverage.dir}/coverage.txt" /&gt;
        &lt;html outfile="${coverage.dir}/coverage.html" /&gt;
      &lt;/report&gt;
    &lt;/emma&gt;
  &lt;/target&gt;</pre><p>When EMMA instrumentation is enabled via
<tt class="option">emma.enabled</tt> build property, the sequence of logic here is
as follows:

      <div class="calloutlist"><table summary="Callout list" border="0"><tr><td align="left" valign="top" width="5%"><a name="B0"></a><a href="#B0-co"><img border="0" alt="1" src="../images/callouts/1.png"></a> </td><td align="left" valign="top"><p>Again, there is a
<span><b class="command">emma</b></span> helper target to set <tt class="option">emma.enabled</tt>
to <tt class="option">true</tt>. Additionally, this target defines
<tt class="option">${out.instr.dir}</tt> property for coverage-instrumented output. It is
important that this property exist only when
<tt class="option">emma.enabled=true</tt>, as you will see later.</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="B0.5"></a><a href="#B0.5-co"><img border="0" alt="2" src="../images/callouts/2.png"></a> </td><td align="left" valign="top"><p>EMMA's offline
instrumentor executes and copies instrumented classes into
<tt class="option">${out.instr.dir}</tt>. Class <span class="emphasis"><em>metadata</em></span> is
dumped into a <tt class="filename">metadata.emma</tt> file. (Note that
<span><b class="command">&lt;instr&gt;</b></span> accepts the same
<tt class="option">run.classpath</tt> path element reference as the original build:
this is what makes EMMA so easy to integrate with ANT.)</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="B1"></a><a href="#B1-co"><img border="0" alt="3" src="../images/callouts/3.png"></a> </td><td align="left" valign="top"><p>The application runs with
instrumented classes.</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="B2"></a><a href="#B2-co"><img border="0" alt="4" src="../images/callouts/4.png"></a> </td><td align="left" valign="top"><p>In version 2.0, EMMA's
runtime coverage data is dumped by a JVM exit handler and for this to happen
<span><b class="command">&lt;java&gt;</b></span> needs to be forked.</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="B3"></a><a href="#B3-co"><img border="0" alt="5" src="../images/callouts/5.png"></a> </td><td align="left" valign="top"><p>As in the command line
case, the instrumented classes need to be first in the classpath. Note that
this only happens when <tt class="option">${out.instr.dir}</tt> property has been
defined by <span><b class="command">emma</b></span> helper target. Also,
<span><b class="command">&lt;java&gt;</b></span> needs to have <tt class="filename">emma.jar</tt>
in its classpath (recollect the path reference created in <a href="ar01s03.html#setupANT" title="3.1.&nbsp;Adding EMMA tasks to your ANT build">Section&nbsp;3.1, &ldquo;Adding EMMA tasks to your ANT build&rdquo;</a>).</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="B4"></a><a href="#B4-co"><img border="0" alt="6" src="../images/callouts/6.png"></a> </td><td align="left" valign="top"><p>For certainty,
<span><b class="command">&lt;java&gt;</b></span> is configured with an explicit filename that
accepts <span class="emphasis"><em>runtime coverage profile</em></span> data.</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="B5"></a><a href="#B5-co"><img border="0" alt="7" src="../images/callouts/7.png"></a> </td><td align="left" valign="top"><p>EMMA report processor
executes.</p></td></tr><tr><td align="left" valign="top" width="5%"><a name="B6"></a><a href="#B6-co"><img border="0" alt="8" src="../images/callouts/8.png"></a> </td><td align="left" valign="top"><p>The report processor
combines the class metadata and runtime coverage profile to produce a couple
of reports.</p></td></tr></table></div>

      <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Overwrite mode</h3><p>EMMA can do "in place" instrumentation
(<span class="emphasis"><em>overwrite</em></span> mode), whereby the classes and jar files are
overwritten with their instrumented versions. However, this is easy to
abuse, so the build above is being careful and creates a separate directory
for coverage-instrumented output.</p></div>

</p><p>Let's see the new build in action. Again, code coverage is
turned on only if <span><b class="command">emma</b></span> target appears on ANT command line
before any run targets:</p><pre class="screen">
&gt;ant emma run
Buildfile: build.xml

emma:

init:
    [mkdir] Created dir: .../examples/out

compile:
    [javac] Compiling 4 source files to .../examples/out

run:
[emma.instr] processing instrumentation path ...
[emma.instr] instrumentation path processed in 200 ms
[emma.instr] [3 class(es) instrumented, 0 resource(s) copied]
[emma.instr] metadata merged into [.../coverage/metadata.emma] {in 31 ms}
     [java] EMMA: collecting runtime coverage data ...
     [java] main(): running doSearch()...
     [java] main(): done
     [java] EMMA: runtime coverage data written to [.../coverage/coverage.emma] {in 15 ms}
[emma.report] 2 file(s) read and merged in 0 ms
[emma.report] writing [txt] report to [.../coverage/coverage.txt] ...
[emma.report] writing [html] report to [.../coverage/coverage.html] ...

BUILD SUCCESSFUL
Total time: 7 seconds</pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Instrumenting just the right classes</h3><p>Unlike some other tools, EMMA's design is based around
filtering for the right set of classes at instrumentation time. Doing so
allows EMMA to scale to enterprise size projects and ensures the best
performance throughout all three offline stages: instrumentation, execution,
and reporting. To select a subset of classes to be processed, you can use
two complementary techniques:
        <div class="orderedlist"><ol type="1" compact="compact"><li><p>segment your ANT path elements well, do not lump
everything into just one <tt class="option">path</tt>. Specifically, keep
third-party libraries, your application classes, and testcase classes in
separate path elements. It will be easy to combine them when needed and code
coverage will be easier because you will have just the right path element to
use as <span><b class="command">&lt;instr&gt;</b></span>'s <tt class="option">instrpath</tt>
attribute or nested element: your application classes.</p></li><li><p>additionally, you can give
<span><b class="command">&lt;instr&gt;</b></span> several <span><b class="command">&lt;filter&gt;</b></span>
nested elements, each potentially containing a list of class name
inclusion/exclusion patterns. This will allow you to zoom in on just the
right part of your application. And adding an ANT command-line override for
one of those will allow every developer on the team to narrow things down to
their own module. See the exact <a class="olink" href="../reference/ch02s03s02.html#tool-ref.instr.filter.ANT">ANT syntax for specifying coverage filters</a> in
the reference manual.</p></li></ol></div></p></div><p>Note that your build can contain several instrumentation and
execution stages and <span><b class="command">&lt;report&gt;</b></span> will happily merge
all of the results in memory before generating the reports. To merge all
files on disk (for maintenance and disk storage reasons) you can use
<span><b class="command">&lt;merge&gt;</b></span> sub-task:

<pre class="programlisting">
  &lt;target name="merge" description="demonstrates dump file merging" &gt;
    &lt;emma&gt;
      &lt;merge outfile="${coverage.dir}/session.emma" &gt;
        &lt;fileset dir="${coverage.dir}" &gt;
          &lt;include name="*.emma" /&gt;
        &lt;/fileset&gt;
      &lt;/merge&gt;
    &lt;/emma&gt;
  &lt;/target&gt;</pre>

In EMMA's offline mode, you are in complete control of
mixing and matching metadata and coverage data from different application
runs. You can instruct all tools to merge all data in the same file or keep
everything in separate file repositories. EMMA tools default to
<tt class="option">merge=true</tt> output file mode for metadata and runtime
coverage data, but properties exist to alter this behavior. See <a class="olink" href="../reference/ch03.html">Chapter3, EMMA Property Reference</a> in the reference manual for
full details on EMMA configuration.</p><p>To summarize, an existing <tt class="filename">build.xml</tt> can be
converted to use EMMA's offline instrumentation mode by following these steps:
	<div class="orderedlist"><ol type="1" compact="compact"><li><p>add EMMA task definitions</p></li><li><p>add the necessary <span><b class="command">&lt;instr&gt;</b></span> tasks,
making sure that the application classes are instrumented before they are
used at runtime</p></li><li><p>configure classpaths and coverage inclusion/exclusion
filters such that only your application classes, not third-party libraries
or testcases, are instrumented</p></li><li><p>make sure the instrumented classes will be
<span class="emphasis"><em>prepended</em></span> to your application's runtime classpath (that
is, if you are not packaging them as EJBs, a web app, etc
instead)</p></li><li><p>add a <span><b class="command">&lt;report&gt;</b></span> task that
aggregates class metadata and runtime coverage profiles for reporting as
needed</p></li><li><p>make sure there is a way to turn coverage instrumentation
on and off (you can use either the existing ANT solutions for that or the
<tt class="option">enabled</tt> attribute on all EMMA tasks)</p></li></ol></div> 
</p><p><b>Further reading.&nbsp;</b>This has been a quick intro to EMMA's offline instrumentation
	tools for ANT. For further details read the reference manual
	starting with <a class="olink" href="../reference/ch02s03.html">Section3, &lt;instr&gt;/instr</a>.</p></div><div class="navfooter"><hr><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ar01s03s02.html"><img src="../images/prev.gif" alt="Prev"></a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ar01s03.html"><img src="../images/up.gif" alt="Up"></a></td><td align="right" width="40%">&nbsp;</td></tr><tr><td valign="top" align="left" width="40%">3.2.&nbsp;<span><b class="command">&lt;emmajava&gt;</b></span>: instrumenting Java classes
on-the-fly&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="userguide.html"><img src="../images/home.gif" alt="Home"></a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></body></html>